package com.digua.baseiot.ui

import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.CompoundButton
import android.widget.RadioButton
import android.widget.Toast
import android_serialport_api.SerialPortFinder
import com.blankj.utilcode.util.TimeUtils
import com.digua.base.util.StrUtil
import com.digua.base.util.ThreadUtil
import com.digua.base.util.Toasts
import com.digua.baseiot.base.BaseActivity
import com.digua.baseiot.databinding.ActivitySerialPortTestBinding
import com.digua.baseiot.uitls.MathUtil
import com.digua.baseiot.uitls.SerialHelper
import java.nio.charset.StandardCharsets
import java.util.Date

class SerialPortTestActivity : BaseActivity<ActivitySerialPortTestBinding>() {
    private lateinit var portAdapter: ArrayAdapter<String>
    private var serialPorts = ArrayList<String>()
    private val baudRates = arrayOf("300", "600", "1200", "2400", "4800", "9600", "14400", "19200", "38400", "56000", "57600", "115200")
    private var serialHelper: SerialHelper? = null
    private var selectParity = 0
    private var selectDataBits = 8
    private var selectStopBit = 1
    private val selectPort = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initUI()
        initData()
    }

    private fun initUI() {
        portAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item)
        ui.port.adapter = portAdapter
        ui.baudRate.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, baudRates)

        ui.port.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                serialHelper?.close()
                serialHelper = null
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }
        ui.baudRate.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                serialHelper?.close()
                serialHelper = null
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }

        ui.clear.setOnClickListener { ui.data.text = "" }

        ui.send.setOnClickListener {
            if (ui.send.text != "停止发送") {
                sendMsg()
            } else {
                ui.send.text = "发送"
            }
        }

        ui.portSwitch.setOnCheckedChangeListener { buttonView: CompoundButton?, isChecked: Boolean ->
            if (isChecked) {
                openSerial()
            } else {
                serialHelper?.close()
                serialHelper = null
                Toasts.showLong("关闭串口成功")
            }
        }
    }

    private fun initData() {
        // 列举可用的USB设备
        serialPorts = SerialPortFinder().allDevicesPath.toList() as ArrayList<String>
        portAdapter.clear()
        portAdapter.addAll(serialPorts)
        portAdapter.notifyDataSetChanged()
    }


    fun openSerial() {
        val port = ui.port.selectedItem?.let { it as String } ?: ""
        val baudRate = ui.baudRate.selectedItem?.let { it as String } ?: ""
        if (StrUtil.hasBlank(port, baudRate)) {
            Toasts.showLong("连接参数不全，连接失败")
            return
        }
        serialHelper = object : SerialHelper(port, baudRate.toInt(), selectParity, selectDataBits, selectStopBit) {
            override fun onDataReceived(buff: ByteArray?) {
                try {
                    val sb = StringBuilder()
                    sb.append(TimeUtils.date2String(Date(), "HH:mm:ss.SSS"))
                    sb.append("[$selectPort]")
                    sb.append("[Read]")
                    sb.append("[${getDataType()}] ")
                    if (getDataTypeHasHex()) {
                        sb.append(MathUtil.bytesToHex(buff))
                    } else {
                        sb.append(String(buff!!, StandardCharsets.UTF_8))
                    }
                    sb.append("\r\n")
                    ui.data.append(sb.toString())
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
            }

            override fun onSendDataReceived(buff: ByteArray?) {
                try {
                    val sb = StringBuilder()
                    sb.append(TimeUtils.date2String(Date(), "HH:mm:ss.SSS"))
                    sb.append("[$selectPort]")
                    sb.append("[Send]")
                    sb.append("[${getDataType()}] ")
                    if (getDataTypeHasHex()) {
                        sb.append(MathUtil.bytesToHex(buff))
                    } else {
                        sb.append(String(buff!!, StandardCharsets.UTF_8))
                    }
                    sb.append("\r\n")
                    ui.data.append(sb.toString())
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
            }
        }
        try {
            serialHelper?.open1()
            Toasts.showLong("打开串口成功！")
            Toast.makeText(this, "打开串口成功！", Toast.LENGTH_SHORT).show()
        } catch (e: java.lang.Exception) {
            Toasts.showLong("打开串口失败：${e.message}")
            serialHelper = null
            if (ui.portSwitch.isChecked()) ui.portSwitch.toggle()
        }
    }

    private fun sendMsg() {
        if (serialHelper == null) {
            Toasts.showLong("未连接")
            return
        }
        if (ui.content.text.toString().isNullOrBlank()) {
            Toasts.showLong("请输入要发送的内容")
            return
        }

        val timeStr = ui.time.text.toString()
        val time = if (timeStr.isNullOrBlank()) 0 else timeStr.trim().toLong()
        sendMessage(ui.content.text.toString().trim(), time)
    }

    private fun sendMessage(content: String, time: Long) {
        if (getDataTypeHasHex()) {
            serialHelper?.send(MathUtil.hexString2Bytes(content))
        } else {
            serialHelper?.send(content.toByteArray())
        }
        ThreadUtil.postDelayed(time) { runOnUiThread { sendMessage(content, time) } }
    }

    fun getDataType() = findViewById<RadioButton>(ui.dataType.checkedRadioButtonId).tag.toString()

    fun getDataTypeHasHex() = getDataType() == "Hex"

}